﻿using System.Collections;
using UnityEngine;

namespace MassiveBattle.Controller
{
	public class Projectile : MonoBehaviour, Manager.IWorker
	{
		public Manager.BaseManager Manager { get; private set; }

		private BaseController source;
		private BaseController target;
		private ProjectileInfo projectileInfo;
		private GameObject projectileHitRes;

		public void SetManager(Manager.BaseManager manager)
		{
			Manager = manager;
		}

		public void Fire(BaseController source, BaseController target, Vector3 position, float time, ProjectileInfo projectileInfo, GameObject projectileHitRes)
		{
			this.source = source;
			this.target = target;
			this.projectileInfo = projectileInfo;
			this.projectileHitRes = projectileHitRes;

			StartCoroutine(FireCoroutine(transform.position, position, time));
		}

		private IEnumerator FireCoroutine(Vector3 start, Vector3 end, float timeTotal)
		{
			for (float timeCur = 0f; ; timeCur += Time.deltaTime)
			{
				transform.position = Vector3.Lerp(start, end, timeCur / timeTotal);

				if (timeCur > timeTotal)
					break;

				yield return null;
			}

			OnFireComplete();
		}

		private void OnFireComplete()
		{
			if (target != null)
			{
				if (source.IsHealer)
				{
					int point = Utility.GetHealPoint(Manager, source.Stat, target.Stat);

					target.Heal(point);
				}
				else
				{
					int point = Utility.GetDamagePoint(Manager, source.Stat, target.Stat);

					target.Damage(point, false, source);

					if (projectileHitRes != null)
					{
						var effect = Manager.GameObjectPool[projectileHitRes].transform;
						effect.gameObject.SetActive(true);
						effect.parent = transform;
						effect.localPosition = Vector3.zero;
						effect.localRotation = Quaternion.identity;
						effect.localScale = Vector3.one;
						effect.parent = null;

						Manager.StartCoroutine(DestroyHitEffectCoroutine(effect.gameObject));
					}

					if (projectileInfo.projectileHitSound != null)
					{
						target.PlayProjectileHitSound(projectileInfo.projectileHitSoundVolume, projectileInfo.projectileHitSound);
						//Debug.LogError("play projectile hit sound");
					}
					if (projectileInfo.shakeCamOnArrive)
					{
						Camera.main.gameObject.GetComponent<Thinksquirrel.Utilities.CameraShake>().Shake();
					}
				}
			}

			Manager.GameObjectPool.Release(gameObject);
		}

		private IEnumerator DestroyHitEffectCoroutine(GameObject effect)
		{
			yield return new WaitForSeconds(2f);

			Manager.GameObjectPool.Release(effect);
		}
	}
}
